---@class TBS.ReportMgr
local ReportMgr = TBS.CreateSingleton("ReportMgr")
local this = ReportMgr
function ReportMgr.OnCreate()
    ---@type TBS.CommandBase[][]
    this.commandList = {}
    ---@type TBS.CommandBase[]
    this.initCmdList = {}
    this.maxTurn = dataTable.getGlobalInt(387)
    this.turnCount = 0
    this.newCmdStr = ""
    this.reportPath = ""
end
function ReportMgr.OnDestroy()
    if this.commandList then
        for k,v in pairs(this.commandList) do
            for k2,v2 in pairs(v) do
                v2:OnDestroy()
            end
        end
    end
    this.commandList = nil
    this.initCmdList = nil
    this.reportPath = nil
end
function ReportMgr.Clear()
    if this.commandList then
        for k,v in pairs(this.commandList) do
            for k2,v2 in pairs(v) do
                v2:OnDestroy()
            end
        end
    end
    table.clear(this.initCmdList)
    table.clear(this.commandList)
end
function ReportMgr.InitReport(cmd)
    for k,v in pairs(this.commandList) do
        for k2,cmd in pairs(v) do
            cmd:Reset()
        end
    end
    if cmd == "" then
        this.ResetCurReport()
    else
        this.ParseReport(cmd)
    end
end
function ReportMgr.ResetCurReport()
    for k,v in pairs(this.initCmdList) do
        v:Reset()
        v:Execute()
    end
    TBS.ActorMgr.InitLeaderSkill()
end
---@param command TBS.CommandBase
function ReportMgr.InitLeaderSkill(command)
    if command.action ~= TBS.Config.FightActionType.ATTACK then
        return
    end
    --local player = TBS.ActorMgr.GetActor(command.fighterId)
    --if player and player:IsLeader() and command.sourceSkillUniqueId == 0 then
    --    TBS.ActorMgr.SetLeaderSkill(player:GetGroupId(),command.skillId)
   -- end
end
function ReportMgr.ParseReport(report)
    if string.IsNilOrEmpty(report) then
        return
    end
    this.turnCount = 0
    local cid = 1
    report = decodeJsonStrToTabel(report)
    table.clear(this.commandList)
    table.clear(this.initCmdList)
    for k, v in pairs(report) do
        local frame = toNumber(v["1"]);
        local action = toNumber(v["2"]);
        local type = v["3"] or 0
        local value = v["4"];
        if this.turnCount < frame then
            this.turnCount = frame
        end
        if action == TBS.Config.FightActionType.INIT then
            local fighterId = value["1"];
            local modelId = value["2"];
            --local maxHP = value["3"];
            local hp = value["4"];
            --local maxEnergy = value["5"];
            --local energy = value["6"];
            local isBoss = value["7"]
            local groupIndex = value["8"];
            local level = value["9"];
            local groupId = value["10"]
            local name = value["11"]
            local playerId = value["12"]
            local actorType
            if type == 1 then
                actorType = TBS.Config.ActorType.leader
            else
                if isBoss == 1 then
                    actorType = TBS.Config.ActorType.boss
                else
                    actorType = TBS.Config.ActorType.player
                end
            end
            local command = TBS.CommandInit.New()
            command.cid = cid
            command.frame = frame
            command.action = action
            command.type = type
            command.fighterId = tostring(fighterId)
            command.modelId = modelId
            command.maxHP = hp
            command.hp = hp
            command.actorType = actorType
            command.groupId = groupId
            command.groupIndex = groupIndex
            command.playerName = name
            command.playerId = playerId
            command.level = level
            table.insert(this.initCmdList,command)
            command:Execute()
        elseif action == TBS.Config.FightActionType.ATTACK then
            local fighterId = value["1"];
           -- local targetId = value["2"];
            local skillId = value["3"];
            --local attackSpeed = value["4"];
           -- local skillFixedPos = value["7"];
            local skillUniqueId = value["10"];
            local sourceSkillId = value["11"];
            local command = TBS.CommandAttack.New()
            command.cid = cid
            command.frame = frame;
            command.action = action;
            command.type = type;
            command.fighterId = tostring(fighterId);
            command.skillId = skillId;
            command.skillUniqueId = skillUniqueId
            command.sourceSkillUniqueId = sourceSkillId
            this.AddCommand(frame, command)
            --this.InitLeaderSkill(command)
        elseif action == TBS.Config.FightActionType.DAMAGE then
            local fighterId = value["1"];
            local targetId = value["2"];
            local damage = value["3"];
            local damageType = value["4"];
            local skillId = value["5"];
            --local skillFrame = value["6"];
            local skillUniqueId = value["10"]

            local command = TBS.CommandDamage.New();
            command.cid = cid
            command.frame = frame;
            command.action = action;
            command.type = type;
            command.fighterId = tostring(fighterId);
            command.targetId = tostring(targetId);
            command.damage = damage;
            command.damageType = damageType;
            command.skillId = skillId;
            command.skillUniqueId = skillUniqueId
            this.AddCommand(frame, command)
        elseif action == TBS.Config.FightActionType.BUFF then
            local fighterId = value["1"];
            local targetId = value["2"];
            local buffId = value["3"];--typeId
            --local buffShow = nil; --value["4"]; 沒使用了
            local buffServerId = value["4"] or buffId;--唯一id  向后兼容协议
            --local buffServerId = buffId;--唯一id  向后兼容协议
            local buffOverlay = value["5"] or 1;--buff层数(默认为1)  向后兼容协议
            --local buffPoolType = value["6"]; --池类型 1血池 2护盾池
            --local buffPoolMax = value["7"];
            --local buffPoolCurrent = value["8"];
            local sourceSkill = value["9"]
            local sourceUniqueSkill = value["10"]
            local command = TBS.CommandBuff.New()
            command.cid = cid
            command.frame = frame;
            command.action = action;
            command.type = type;
            command.fighterId = tostring(fighterId);
            command.targetId = tostring(targetId);
            command.buffId = buffId;
            command.buffOverlay = buffOverlay;
            command.sourceSkill = sourceSkill
            command.sourceUniqueSkill = sourceUniqueSkill or 0
            this.AddCommand(frame, command);
        elseif action == TBS.Config.FightActionType.ROUND then
            local fighterId = value["1"];
            local command = TBS.CommandRound.New()
            command.cid = cid
            command.frame = frame;
            command.action = action;
            command.type = type;
            command.fighterId = tostring(fighterId);
            this.AddCommand(frame, command);
        elseif action == TBS.Config.FightActionType.DEATH then
            local fighterId = value["1"]
            local killerId = value["2"]
            local command = TBS.CommandDead.New()
            command.cid = cid
            command.frame = frame;
            command.action = action;
            command.type = type;
            command.fighterId = tostring(fighterId)
            command.killerId = tostring(killerId)
            this.AddCommand(frame, command)
        elseif action == TBS.Config.FightActionType.Hit then
            local fighterId = value["1"]
            local skillId = value["3"]
            local skillUniqueId = value["10"]
            local command = TBS.CommandHit.New()
            command.fighterId = tostring(fighterId)
            command.skillId = skillId
            command.skillUniqueId = skillUniqueId
            this.AddCommand(frame,command)
        else
            logError("额外的command:"..action)
        end
        cid = cid + 1
    end
    TBS.ActorMgr.InitLeaderSkill()
end
---@param commandInfo TBS.CommandBase
function ReportMgr.AddCommand(frame, commandInfo)
    if not this.commandList[frame] then
        this.commandList[frame] = {}
    end
    local tb = this.commandList[frame]
    table.insert(tb,commandInfo)
end
function ReportMgr.GetCommandList(frame)
    return this.commandList[frame]
end
function ReportMgr.ParseGroupPosition(position)
    local groupId = math.floor((position-1) / 6 + 1)
    local groupIndex = (position-1) % 6 + 1
    return groupId,groupIndex
end
---@param curCmd TBS.CommandBase
---@return TBS.CommandBase
function ReportMgr.GetPreCmd(curCmd)
    local frame = curCmd.frame
    local _list = this.GetCommandList(frame)
    if not _list then return nil end
    local cmd
    for k,v in pairs(_list) do
        if v == curCmd then
            return cmd
        else
            cmd = v
        end
    end
    return nil
end
function ReportMgr.GetPreSkillCmd(curCmd,skillUniqueId)
    local frame = curCmd.frame
    local _list = this.GetCommandList(frame)
    if not _list then return nil end
    local cmd
    for k,v in pairs(_list) do
        if v == curCmd then
            return cmd
        elseif v.action == TBS.Config.FightActionType.ATTACK and v.skillUniqueId == skillUniqueId then
            cmd = v
        end
    end
    return nil
end